﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace SharePoint.Orm {
	public class SPQueryable {
		private readonly SPDataContext _dataContext;

		public SPQueryable(SPDataContext dataContext) {
			_dataContext = dataContext;
		}

		public SPDataContext DataContext {
			get { return _dataContext; }
		}
	}

	public class SPQueryable<T> : SPQueryable, IQueryable<T> {
		public SPQueryable(SPDataContext dataContext)
			: base(dataContext) {
			Provider = new SPQueryProvider(DataContext);
			Expression = Expression.Constant(this);
		}

		public SPQueryable(SPDataContext dataContext, IQueryProvider provider, Expression expression)
			: base(dataContext) {
			if (provider == null) {
				throw new ArgumentNullException("provider");
			}
			if (expression == null) {
				throw new ArgumentNullException("expression");
			}
			if (!typeof(IQueryable<T>).IsAssignableFrom(expression.Type)) {
				throw new ArgumentOutOfRangeException("expression");
			}
			Provider = provider;
			Expression = expression;
		}

		public IQueryProvider Provider { get; private set; }
		public Expression Expression { get; private set; }

		public IEnumerator<T> GetEnumerator() {
			return (Provider.Execute<IEnumerable<T>>(Expression)).GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator() {
			return GetEnumerator();
		}

		public Type ElementType {
			get { return typeof(T); }
		}
	}
}
